iT邦幫忙

2021 iThome 鐵人賽

DAY 23
0

Boxenn::UseCase 中處理 validation?

dry-monads 中有提供 validate 的功能,他的特色是不會中斷執行,而是等到所有 list 中的 validate 都執行完後再一次回傳所有的 failure。

# create_order.rb
class ValidOrder < Boxenn::UseCase
	option :repo, default: -> { OrderRepository.new }

  def steps(serial_number:)
		order = retrieve_order(serial_number)
    yield List::Validated[
      valid_capacity(order),
      valid_price(order),
    ].traverse.to_result
		Success()
  end

  private

	def retrieve_order(serial_number)
		repo.find_by_identity(serial_number: serial_number)
	end

	def valid_capacity(order)
		return Invalid(:capacity_error) if order.capacity < 0

		Valid(Unit)
	end

	def valid_price(order)
		return Invalid(:price_error) if order.price < 0
		
		Valid(Unit)
	end	
end

result = ValidOrder.new.call(serial_number: 'ABC-1234567890')
# 成功
# => Success()
# 失敗
# => Failure(List[:capacity_error, :price_error])

這樣的特性用在參數的 validation 很方便,但會有一些問題產生:

  • 回傳 List 物件(dry-monads 自定義的),而在未使用 List::Validated 的 use case 中不會特別在 failure 回傳 List,使得介面不統一。
  • 因為 List::Validated 當中的 method 全部都會執行,如果其中一個 method 執行失敗,後續仍會繼續執行,這與原本 use case 設計理念中的 sequential 性質有些違背。
  • 上述所說的性質非常適合用在 controller 接到參數後的驗證,但這個職責不應該放在 DLL(Domain Logic Layer) 處理。

下篇會來聊聊 Boxenn::UseCase 目前的 error handling ,以及遇到的阻礙。


上一篇
[DAY22] Boxenn Use Case Spec
下一篇
[DAY24] Boxenn Use Case 的 error handle
系列文
在 Ruby on Rails 中導入 Domain-Driven Design 是不是搞錯了什麼?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言